package com.yanqu.road.server.manager.banquet;

import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.banquet.BanquetGiftInfo;
import com.yanqu.road.entity.banquet.BanquetInfo;
import com.yanqu.road.entity.banquet.auto.CrossBanquetAutoData;
import com.yanqu.road.entity.banquet.auto.CrossBanquetAutoJoinLog;
import com.yanqu.road.entity.player.UserBaseInfo;
import com.yanqu.road.logic.bussiness.crossbanquet.CrossBanquetBussiness;
import com.yanqu.road.message.YanQuMessage;
import com.yanqu.road.pb.banquet.BanquetProto;
import com.yanqu.road.pb.banquet.CrossBanquetProto;
import com.yanqu.road.server.TempMgr;
import com.yanqu.road.server.logic.MessageHelper;
import com.yanqu.road.server.manager.activity.ActivityInfoMgr;
import com.yanqu.road.server.manager.user.CrossUserMgr;
import com.yanqu.road.server.protocol.Protocol;
import com.yanqu.road.utils.ConfigHelper;
import com.yanqu.road.utils.RandomHelper;
import com.yanqu.road.utils.YanQuMessageUtils;
import com.yanqu.road.utils.string.StringUtils;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

public class CrossBanquetAutoMgr extends TempMgr {

    private static List<Integer> initActivityList = new ArrayList<>();

    private static Map<Integer,Map<Long, CrossBanquetAutoData>> userCrossBanquetDataMap = new ConcurrentHashMap<>();

    private static RandomHelper random = new RandomHelper();

    private static int logLimitCount = 30;

    public static int getLogLimitCount() {
        return logLimitCount;
    }

    public static CrossBanquetAutoData getUserData(int activityId, long userId){
        if(activityId != 0){
            initActiviy(activityId);
            if(userCrossBanquetDataMap.containsKey(activityId)){
                if(userCrossBanquetDataMap.get(activityId).containsKey(userId)){
                    return userCrossBanquetDataMap.get(activityId).get(userId);
                }
            }
        }else{
            for(int acId : userCrossBanquetDataMap.keySet()){
                if(userCrossBanquetDataMap.get(acId).containsKey(userId)){
                    return userCrossBanquetDataMap.get(acId).get(userId);
                }
            }
        }
        return null;
    }

    public static CrossBanquetAutoData initUserData(int activityId,long userId){
        initActiviy(activityId);
        Map<Long, CrossBanquetAutoData> userDataMap = userCrossBanquetDataMap.get(activityId);
        if(!userDataMap.containsKey(userId)){
            synchronized (userDataMap){
                if(!userDataMap.containsKey(userId)){
                    CrossBanquetAutoData userData = new CrossBanquetAutoData();
                    userData.setActivityId(activityId);
                    userData.setUserId(userId);
                    userData.setInsertOption();
                    userDataMap.put(userId,userData);
                }
            }
        }
        CrossBanquetAutoData userData = userDataMap.get(userId);

        return userData;
    }

    public static void saveUserSet(long userId,long serverId, CrossBanquetProto.CrossBanquetAutoJoinSetReq reqMsg) {
        CrossBanquetProto.CrossToBanquetAutoJoinSetResp.Builder respMsg = CrossBanquetProto.CrossToBanquetAutoJoinSetResp.newBuilder();
        respMsg.setAcId(reqMsg.getAcId());
        respMsg.setUserId(userId);
        respMsg.setConsume(reqMsg.getConsume());
        respMsg.setRet(0);

        int activityId = reqMsg.getAcId();

        CrossBanquetAutoData userData = getUserData(activityId,userId);
        if(userData == null){
            userData = initUserData(activityId,userId);
        }
        userData.setServerId(serverId);
        userData.setTitleAdd(reqMsg.getTitleAdd());
        userData.setSkillAdd(reqMsg.getSkillAdd());

        Map<String, Integer> itemMap = userData.getItemMap();
        Map<Integer, Integer> joinTimesMap = userData.getJoinTimesMap();
        if(reqMsg.getJoinsList().size() > 0){
            for(CrossBanquetProto.BanquetAutoJoinTmp msg : reqMsg.getJoinsList()){
                if(msg.getNum() > 0){
                    itemMap.put(msg.getConsume(),itemMap.getOrDefault(msg.getConsume(),0) + msg.getNum());
                }else{
                    Map<Integer, BanquetGiftInfo> giftInfoMap = CrossBanquetConfigMgr.getBanquetGiftByConsume(5,msg.getConsume());
                    //小于0就是取消了这个类型的回宴会
                    CrossBanquetProto.BanquetAutoJoinTmp.Builder itemMsg = CrossBanquetProto.BanquetAutoJoinTmp.newBuilder();
                    itemMsg.setConsume(msg.getConsume());
                    itemMsg.setNum(itemMap.get(msg.getConsume()));
                    respMsg.addJoins(itemMsg);
                    for(BanquetGiftInfo giftInfo : giftInfoMap.values()){
                        int rewardIndex= giftInfo.getId() % 10;
                        if(rewardIndex == 0){
                            respMsg.setType(1);
                            respMsg.setJoinTimes1(joinTimesMap.getOrDefault(rewardIndex,0));
                            joinTimesMap.put(rewardIndex,0);
                        }else if(rewardIndex == 1){
                            respMsg.setType(2);
                            respMsg.setJoinTimes2(joinTimesMap.getOrDefault(rewardIndex,0));
                            joinTimesMap.put(rewardIndex,0);
                        }else if(rewardIndex == 2){
                            respMsg.setType(3);
                            respMsg.setJoinTimes3(joinTimesMap.getOrDefault(rewardIndex,0));
                            joinTimesMap.put(rewardIndex,0);
                        }
                        //一个就行了，相同随礼的一个 % 10都是0，除非配置不一样的消耗，不能配不一样的
                        break;
                    }

                    itemMap.put(msg.getConsume(),0);
                }
            }
            userData.setItemMap(itemMap);
            userData.setJoinTimesMap(joinTimesMap);
        }
        boolean isAllCancel = true;
        for(int timers : userData.getItemMap().values()){
            if(timers != 0){
                isAllCancel = false;
            }
        }
        if(isAllCancel){
            respMsg.setIntegral(userData.getAllIntegral());
            userData.setAllIntegral(0);
        }
        YanQuMessage pbMsg = YanQuMessageUtils.buildMessage(Protocol.S_BANQUET_CROSS_ACTIVITY_JOIN_AUTO_RESP, respMsg);
        MessageHelper.sendPacket(serverId, userId, pbMsg);
        syncUserData(userId,serverId,activityId);
        List<String> consumeList = new ArrayList<>();
        for(String consume : itemMap.keySet()){
            if(itemMap.get(consume) > 0){
                consumeList.add(consume);
            }
        }
        if(consumeList.size() > 0){
            CrossBanquetMgr.updateCrossAutoPartySetting(serverId,userId,consumeList);
        }
    }

    //获取玩家对应的活动类型是不是有自动赴宴不能取消的类型
    public static boolean canSetGiftIdList(long userId,BanquetInfo banquetInfo,List<Integer> gitfIdList){
        CrossBanquetAutoData userData = getUserData(0,userId);
        if(userData == null){
            return true;
        }
        List<Integer> needAddList = new ArrayList<>();
        Map<String, Integer> itemMap = userData.getItemMap();
        for(String consume : itemMap.keySet()){
            if(itemMap.get(consume) > 0){
                BanquetGiftInfo giftInfo = CrossBanquetConfigMgr.getBanquetGiftByConsume(banquetInfo,consume);
                if(giftInfo != null){
                    needAddList.add(giftInfo.getId());
                }
            }
        }
        for(int needId : needAddList){
            if(!gitfIdList.contains(needId)){
                return false;
            }
        }
        return true;
    }

    public static void syncUserData(long userId,long serverId,int activityId){
        initActiviy(activityId);
        CrossBanquetProto.BanquetAutoSetSync.Builder syncMsg = CrossBanquetProto.BanquetAutoSetSync.newBuilder();
        syncMsg.setAcId(activityId);
        CrossBanquetAutoData userData = getUserData(activityId,userId);
        Map<String, Integer> itemMap = new ConcurrentHashMap<>();
        if(userData != null){
            itemMap = userData.getItemMap();
        }
        for(String consume : itemMap.keySet()){
            if(itemMap.get(consume) == 0)continue;
            CrossBanquetProto.BanquetAutoJoinTmp.Builder itemMsg = CrossBanquetProto.BanquetAutoJoinTmp.newBuilder();
            itemMsg.setConsume(consume);
            itemMsg.setNum(itemMap.get(consume));
            syncMsg.addJoins(itemMsg);
        }
        YanQuMessage pbMsg = YanQuMessageUtils.buildMessage(Protocol.U_BANQUET_CROSS_ACTIVITY_AUTO_SET_SYNC, syncMsg);
        MessageHelper.sendPacket(serverId, userId, pbMsg);

        if(userData != null){
            CrossBanquetProto.CrossToBanquetAutoJoinSetResp.Builder respMsg = CrossBanquetProto.CrossToBanquetAutoJoinSetResp.newBuilder();
            respMsg.setRet(0);
            respMsg.setUserId(userId);
            boolean isAllCancel = true;
            for(int timers : userData.getItemMap().values()){
                if(timers != 0){
                    isAllCancel = false;
                }
            }
            if(isAllCancel && userData.getAllIntegral() > 0){
                respMsg.setIntegral(userData.getAllIntegral());
                userData.setAllIntegral(0);
            }
            //直接都用这个吧，多发个消息也没事吧
            YanQuMessage pbMsg2 = YanQuMessageUtils.buildMessage(Protocol.S_BANQUET_CROSS_ACTIVITY_JOIN_AUTO_RESP, respMsg);
            MessageHelper.sendPacket(serverId, userId, pbMsg2);
        }
    }


    public static void syncUserData(long userId,long serverId,CrossBanquetProto.CrossBanquetAutoSetSyncReq reqMsg) {
        int activityId = reqMsg.getAcId();
        CrossBanquetAutoData userData = getUserData(activityId,userId);
        if(userData != null){
            userData.setTitleAdd(reqMsg.getTitleAdd());
            userData.setSkillAdd(reqMsg.getSkillAdd());
        }
        syncUserData(userId,serverId,activityId);
    }

    public static void userJoinLog(long userId, long serverId,int activityId) {
        CrossBanquetAutoData userData = getUserData(activityId,userId);
        List<CrossBanquetAutoJoinLog> joinLogs = new ArrayList<>();
        if(userData != null){
            joinLogs = userData.getJoinLogList();
        }
        joinLogs.sort(new Comparator<CrossBanquetAutoJoinLog>() {
            @Override
            public int compare(CrossBanquetAutoJoinLog o1, CrossBanquetAutoJoinLog o2) {
                return Long.compare(o2.getTime(), o1.getTime());
            }
        });
        CrossBanquetProto.BanquetAutoJoinLogResp.Builder respMsg = CrossBanquetProto.BanquetAutoJoinLogResp.newBuilder();
        respMsg.setRet(0);
        for(CrossBanquetAutoJoinLog log : joinLogs){
            UserBaseInfo userBaseInfo = CrossUserMgr.getUserBaseInfo(log.getBanquetUserId());
            if(userBaseInfo == null){
                continue;
            }
            CrossBanquetProto.BanquetAutoJoinLogTmp.Builder logMsg = CrossBanquetProto.BanquetAutoJoinLogTmp.newBuilder();
            logMsg.setUserId(log.getBanquetUserId());
            logMsg.setServerId(userBaseInfo.getServerId());
            logMsg.setDecoration(userBaseInfo.getDecoration());
            logMsg.setVipExp(userBaseInfo.getVipExp());
            logMsg.setNickName(userBaseInfo.getNickName());
            logMsg.setHideVipAndAddress(userBaseInfo.getHideVipAndAddress());
            logMsg.setTime(log.getTime()/1000);
            logMsg.setOpenItemId(log.getOpenItemId());
            logMsg.setJoinItemId(log.getJoinItemId());
            respMsg.addLogs(logMsg);
        }
        YanQuMessage pbMsg = YanQuMessageUtils.buildMessage(Protocol.U_BANQUET_CROSS_ACTIVITY_JOIN_AUTO_LOG, respMsg);
        MessageHelper.sendPacket(serverId, userId, pbMsg);
    }

    public static String getUserAutoJoinInfo(int acId,long userId){
        CrossBanquetAutoData autoData = getUserData(0,userId);
        if(autoData == null){
            return "";
        };
        List<String> consumeList = new ArrayList<>();
        for(String consume : autoData.getItemMap().keySet()){
            if(autoData.getItemMap().get(consume) > 0){
                consumeList.add(consume);
            }
        }
        return StringUtils.listToString(consumeList,"|");
    }

    public static void banquetAutoList(long userId, long serverId, BanquetProto.BanquetListResp reqMsg) {
        BanquetProto.BanquetListResp.Builder respMsg = reqMsg.toBuilder();
        for(BanquetProto.BanquetTemp.Builder tempMsg : respMsg.getBanquetDataListBuilderList()){
            long banquetUserId = tempMsg.getUserId();
            tempMsg.setAutoJoinInfo(getUserAutoJoinInfo(reqMsg.getAcId(),banquetUserId));
        }
        YanQuMessage pbMsg = YanQuMessageUtils.buildMessage(Protocol.U_BANQUET_LIST, respMsg);
        MessageHelper.sendPacket(serverId, userId, pbMsg);
    }

    //判断玩家是不是设置了自动赴宴，设置了自动赴宴就不能拒绝礼物
    public static boolean isUserAutoJoin(long userId){
        CrossBanquetAutoData autoData = getUserData(0,userId);
        if(autoData != null){
            for(int nums : autoData.getItemMap().values()){
                if(nums > 0){
                    return true;
                }
            }
        }
        return false;
    }

    public static void banquetAutoMemberPage(long userId, long serverId, CrossBanquetProto.CrossBanquetMemberInfoResp reqMsg) {
        CrossBanquetProto.CrossBanquetMemberInfoResp.Builder respMsg = reqMsg.toBuilder();
        CrossBanquetProto.CrossBanquetTemp.Builder tempMsg = respMsg.getBanquetInfo().toBuilder();
        long banquetUserId = tempMsg.getUserId();
        tempMsg.setAutoJoinInfo(getUserAutoJoinInfo(reqMsg.getAcId(),banquetUserId));
        respMsg.setBanquetInfo(tempMsg);
        YanQuMessage pbMsg = YanQuMessageUtils.buildMessage(Protocol.U_BANQUET_CROSS_MEMBER_LIST_PAGE, respMsg);
        MessageHelper.sendPacket(serverId, userId, pbMsg);
    }

    @Override
    public boolean reloadData() {
        return true;
    }

    @Override
    public boolean init() throws Exception {
        return reload();
    }

    @Override
    public boolean reloadConfig() throws Exception {
        return true;
    }

    private static void initActiviy(int activityId){
        if(!initActivityList.contains(activityId)){
            synchronized (initActivityList){
                if(!initActivityList.contains(activityId)){
                    initActivityList.add(activityId);
                    Map<Long, CrossBanquetAutoData> userDataMap = CrossBanquetBussiness.getCrossBanquetAutoMap(activityId);
                    Map<Long, List<CrossBanquetAutoJoinLog>> logMap = CrossBanquetBussiness.getCrossBanquetAutoJoinLogMap(activityId);
                    for(long userId : logMap.keySet()){
                        List<CrossBanquetAutoJoinLog> logList = logMap.get(userId);
                        logList.sort(new Comparator<CrossBanquetAutoJoinLog>() {
                            @Override
                            public int compare(CrossBanquetAutoJoinLog o1, CrossBanquetAutoJoinLog o2) {
                                return Long.compare(o2.getTime(), o1.getTime());
                            }
                        });
                        List<CrossBanquetAutoJoinLog> limitList = new ArrayList<>();
                        int limitCount = logLimitCount;
                        for(int i = 0;i < logList.size(); i++){
                            if(i < limitCount){
                                limitList.add(logList.get(i));
                            }else{
                                if(!logList.get(i).isDealReward()){
                                    limitList.add(logList.get(i));
                                }
                            }
                        }
                        if(!userDataMap.containsKey(userId)){
                            getLogger().error("炸了出现了玩家没有数据却有日志userId:{},activityId:{}",userId,activityId);
                            continue;
                        }
                        userDataMap.get(userId).setJoinLogList(limitList);
                    }
                    userCrossBanquetDataMap.put(activityId,userDataMap);

                }
            }
        }
    }

    public static void activityOver() {
        long nowTime = System.currentTimeMillis();

        for(int activityId : userCrossBanquetDataMap.keySet()){
            ActivityInfo activityInfo = ActivityInfoMgr.getActivityInfo(activityId);
            if(activityInfo != null && nowTime > activityInfo.getEndTime() * 1000){
                Map<Long, CrossBanquetAutoData> userDataMap = userCrossBanquetDataMap.get(activityId);
                int channelId = ConfigHelper.getInt("channelId");
                if(channelId == 666 || channelId == 702 || channelId == 703){
                    getLogger().error("宴会争霸活动{}结束，进行回收",activityInfo.getActivityId());
                }
                //活动结束了，返还所有道具和获得的积分
                for(CrossBanquetAutoData autoData : userDataMap.values()){
                    synchronized (autoData){
                        Map<String, Integer> itemMap = autoData.getItemMap();
                        boolean doIt = false;
                        for(String consume : itemMap.keySet()){
                            if(itemMap.get(consume) > 0){
                                doIt = true;
                                break;
                            }
                        }
                        if(!doIt)continue;
                        CrossBanquetProto.CrossToBanquetAutoJoinSetResp.Builder respMsg = CrossBanquetProto.CrossToBanquetAutoJoinSetResp.newBuilder();
                        respMsg.setRet(0);
                        respMsg.setAcId(activityId);
                        respMsg.setUserId(autoData.getUserId());
                        respMsg.setConsume("");
                        Map<Integer, Integer> joinTimesMap = autoData.getJoinTimesMap();
                        for(String consume : itemMap.keySet()){
                            if(itemMap.get(consume) > 0){
                                Map<Integer, BanquetGiftInfo> giftInfoMap = CrossBanquetConfigMgr.getBanquetGiftByConsume(5,consume);
                                //小于0就是取消了这个类型的回宴会
                                CrossBanquetProto.BanquetAutoJoinTmp.Builder itemMsg = CrossBanquetProto.BanquetAutoJoinTmp.newBuilder();
                                itemMsg.setConsume(consume);
                                itemMsg.setNum(itemMap.get(consume));
                                respMsg.addJoins(itemMsg);
                                respMsg.setType(4);
                                for(BanquetGiftInfo giftInfo : giftInfoMap.values()){
                                    int rewardIndex= giftInfo.getId() % 10;
                                    if(rewardIndex == 0){
                                        respMsg.setJoinTimes1(joinTimesMap.getOrDefault(rewardIndex,0));
                                        joinTimesMap.put(rewardIndex,0);
                                    }else if(rewardIndex == 1){
                                        respMsg.setJoinTimes2(joinTimesMap.getOrDefault(rewardIndex,0));
                                        joinTimesMap.put(rewardIndex,0);
                                    }else if(rewardIndex == 2){
                                        respMsg.setJoinTimes3(joinTimesMap.getOrDefault(rewardIndex,0));
                                        joinTimesMap.put(rewardIndex,0);
                                    }
                                    break;
                                }
                                itemMap.put(consume,0);
                            }
                        }
                        autoData.setItemMap(itemMap);
                        autoData.setJoinTimesMap(joinTimesMap);

                        if(autoData.getAllIntegral() > 0){
                            respMsg.setIntegral(autoData.getAllIntegral());
                            autoData.setAllIntegral(0);
                        }
                        YanQuMessage pbMsg = YanQuMessageUtils.buildMessage(Protocol.S_BANQUET_CROSS_ACTIVITY_JOIN_AUTO_RESP, respMsg);
                        MessageHelper.sendPacket(autoData.getServerId(), autoData.getUserId(), pbMsg);
                        syncUserData(autoData.getUserId(),autoData.getServerId(),activityId);
                    }
                }
            }
        }

        for(int activityId : userCrossBanquetDataMap.keySet()){
            ActivityInfo activityInfo = ActivityInfoMgr.getActivityInfo(activityId);
            if(activityInfo != null && nowTime > activityInfo.getEndShowTime() * 1000){
                userCrossBanquetDataMap.remove(activityId);
            }
        }

    }

    //玩家在线请求加道具
    public static void addUserPopularity(int activityId,long serverId,long userId){
        CrossBanquetProto.CrossAddAutoBanquetPopRewardResp.Builder respMsg = CrossBanquetProto.CrossAddAutoBanquetPopRewardResp.newBuilder();
        respMsg.setAcId(activityId);
        respMsg.setUserId(userId);
        CrossBanquetAutoData autoData = getUserData(activityId,userId);
        synchronized (autoData){
            if (autoData.getAllPopularity() > 0 || autoData.getIngots() > 0 || autoData.getJoinTimes() > 0) {
                respMsg.setPopValue(autoData.getAllPopularity());
                respMsg.setJoinTimes(autoData.getJoinTimes());
                respMsg.setIngots(autoData.getIngots());
                autoData.setAllPopularity(0);
                autoData.setJoinTimes(0);
                autoData.setIngots(0);
                YanQuMessage pbMsg = YanQuMessageUtils.buildMessage(Protocol.S_BANQUET_CROSS_ACTIVITY_REWARD_ADD, respMsg);
                MessageHelper.sendPacket(serverId, userId, pbMsg);
            }
        }
    }

    //通知游戏服拉玩家起来加道具
    public static void noticeUserPopularity(){
        Map<Long,List<Long>> serverUserMap = new ConcurrentHashMap<>();
        for(int activityId : userCrossBanquetDataMap.keySet()){
            Map<Long, CrossBanquetAutoData> autoMap = userCrossBanquetDataMap.get(activityId);
            for(CrossBanquetAutoData autoData : autoMap.values()){
                synchronized (autoData){
                    if (autoData.getAllPopularity() > 0 || autoData.getIngots() > 0 || autoData.getJoinTimes() > 0) {
                        if (!serverUserMap.containsKey(autoData.getServerId())) {
                            serverUserMap.put(autoData.getServerId(), new ArrayList<>());
                        }
                        //一次是个人就好了
                        if (serverUserMap.get(autoData.getServerId()).size() > 10) {
                            continue;
                        }
                        serverUserMap.get(autoData.getServerId()).add(autoData.getUserId());
                    }
                }
            }
            for(long serverId : serverUserMap.keySet()){
                CrossBanquetProto.CrossNoticeAutoBanquetPopRewardReq.Builder reqMsg = CrossBanquetProto.CrossNoticeAutoBanquetPopRewardReq.newBuilder();
                reqMsg.setAcId(activityId);
                reqMsg.addAllUserIds(serverUserMap.get(serverId));
                YanQuMessage pbMsg = YanQuMessageUtils.buildMessage(Protocol.S_BANQUET_CROSS_ACTIVITY_REWARD_NOTICE, reqMsg);
                MessageHelper.sendPacket(serverId, 0, pbMsg);
            }
        }
    }

    public boolean save() {
        noticeUserPopularity();
        activityOver();
        for(Map<Long, CrossBanquetAutoData> autoMap : userCrossBanquetDataMap.values()){
            for(CrossBanquetAutoData autoData : autoMap.values()){
                if(autoData.isInsertOption()){
                    CrossBanquetBussiness.addCrossBanquetAuto(autoData);
                }else if(autoData.isUpdateOption()){
                    CrossBanquetBussiness.updateCrossBanquetAuto(autoData);
                }
                for(CrossBanquetAutoJoinLog log : new ArrayList<>(autoData.getJoinLogList())){
                    if(log.isInsertOption()){
                        CrossBanquetBussiness.addCrossBanquetAutoJoinLog(log);
                    }else if(log.isUpdateOption()){
                        CrossBanquetBussiness.updateCrossBanquetAutoJoinLog(log);
                    }
                }
            }
        }
        return true;
    }

    @Override
    public boolean stop() {
        return false;
    }

}
